package com.lt.flashcard.view;

import java.io.IOException;

import org.apache.log4j.Logger;
import org.bson.types.ObjectId;
import org.zkoss.image.AImage;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.Page;
import org.zkoss.zk.ui.event.UploadEvent;
import org.zkoss.zk.ui.metainfo.ComponentInfo;
import org.zkoss.zk.ui.select.SelectorComposer;
import org.zkoss.zk.ui.select.annotation.Listen;
import org.zkoss.zk.ui.select.annotation.Wire;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zkex.util.Base64Coder;
import org.zkoss.zul.Datebox;
import org.zkoss.zul.Radiogroup;
import org.zkoss.zul.Textbox;

import com.lt.flashcard.Utility;
import com.lt.flashcard.model.entity.User;
import com.lt.flashcard.model.service.AAService;
import com.lt.flashcard.model.service.LearningService;
import com.lt.flashcard.model.service.Repository;
import com.lt.flashcard.model.service.UserService;
import com.mongodb.gridfs.GridFS;

public class ProfileCtrl extends SelectorComposer<Component> {

	private static final long serialVersionUID = 1L;
	private User user;
	
	private static final Logger log = Logger.getLogger(ProfileCtrl.class);

	@Override
	public ComponentInfo doBeforeCompose(Page page, Component parent, ComponentInfo compInfo) {
		String Id = Executions.getCurrent().getParameter("id");
		String uname = Executions.getCurrent().getParameter("uname");
		
		AAService asrv = Repository.getInstance().getAAService();
		User cuser = asrv.getCurrentUser();
		
		if(Utility.isEmptyString(Id) && Utility.isEmptyString(uname)) {
			if(!asrv.isLogin()) {
				Utility.loginOrAccessDenied(false);
				return null;
			}
			else {
				String url = Utility.generateUrl("profile", cuser.getUsername(), null);
    			Utility.redirect(Utility.removeContextPath(url), false);
    			return null;
			}
		}
		else {
			UserService usrv = Repository.getInstance().getUserService();
			user = Utility.isEmptyString(uname) ? usrv.findByID(new Long(Id)) : usrv.findByUsername(uname);
			if(user == null) {
				Utility.displayAccessDenied(false);
				return null;
			}
		}
		
		if(user != null && asrv.isAdmin(user)){
			if(cuser == null || (cuser != null && !user.getId().equals(cuser.getId()))){
				Utility.displayAccessDenied(false);
				return null;
			}
		}
		
		owner = user != null && cuser != null && user.getId().equals(cuser.getId());
		Utility.addOgTag(page,
				String.format("Profile của %s", user.getUsername()),
				String.format("Profile của %s", user.getUsername()),
				Utility.loadImageFromGridFS(user.getAvatar(), Utility.DEF_AVATAR));
		
		return super.doBeforeCompose(page, parent, compInfo);
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}
	
	private boolean owner = false;
	public boolean isOwner() {
		return owner;
	}
	
	public Long numOfFriends() {
		UserService usrv = Repository.getInstance().getUserService();
		return usrv.countNumberOfFriends(getUser());
	}
	
	public Long numOfJouneys() {
		LearningService srv = Repository.getInstance().getLearningService();
		return srv.countJourneyOfUser(getUser().getId());
	}
	
	public Long numOfMedals() {
		LearningService srv = Repository.getInstance().getLearningService();
		return (long) srv.getMedalsOfUser(getUser().getId()).size();
	}
	
	/*
     * delete avatar
     */
    @Listen("onClick=#deleteAvatar")
    public void deleteAvatar(){
    	if(!isOwner()) return;
		try{
			String avatar = user.getAvatar();
			
			if(Utility.isEmptyString(avatar))
				return;
			
			UserService usrv = Repository.getInstance().getUserService();
			user.setAvatar("");
			usrv.save(user);
			
			GridFS fs = Repository.getInstance().getGridFS();
			fs.remove(new ObjectId(avatar));
		}
		catch (Exception e) {
			log.error("Can't delete avatar", e);
		}
		Utility.redirect("", true);
    }
    
    @Wire
	Textbox doodleData;
    
    @Listen("onChange=#doodleData")
    public void onDoodleChange() {
    	if(!isOwner()) return;
    	String data = doodleData.getValue().replace("data:image/png;base64,", "");
    	doodleData.setValue("");
    	try {
    		UserService usrv = Repository.getInstance().getUserService();
    		AImage a = new AImage("", Base64Coder.decode(data.toCharArray()));
    		String img = Utility.saveImage(a.getStreamData());
    		user.setAvatar(img);
    		usrv.save(user);
    		
    		Utility.redirect("", true);
		} catch (Exception e) {
			log.error("Error when update doodle", e);
		}
    }
    
    @Listen("onUpload=#uploadImageFlashcard")
	public void uploadImageFlashcard(UploadEvent event) throws IOException {
    	if(!isOwner()) return;
		org.zkoss.util.media.Media media = event.getMedia();
        if (media instanceof org.zkoss.image.Image) {
        	int h = ((org.zkoss.image.Image) media).getHeight();
            int w = ((org.zkoss.image.Image) media).getWidth();
            if(w > 300 || h > 300) {
            	Clients.evalJavaScript("showNotice('', 'Kích thước tối đa: 300x300px. Vui lòng làm lại.')");
            }
            else {
            	try {
	            	UserService usrv = Repository.getInstance().getUserService();
	            	String img = Utility.saveImage(media.getStreamData());
	            	user.setAvatar(img);
	            	usrv.save(user);
	            	
	            	Utility.redirect("", true);
            	}
            	catch(Exception e) {
            		log.error("Error change avatar", e);
            	}
            } 
        } else {
        	Clients.evalJavaScript("showNotice('', 'Hình không hợp lệ. Vui lòng làm lại.')");
        }
	}
	
	@Wire
	Textbox txtSlogan;
	@Wire
	Textbox txtName;
	@Wire
	Datebox txtBirthday;
	@Wire
	Textbox txtLanguage;
	@Wire
	Textbox txtWorkplace;
	@Wire
	Textbox txtInterest;
	@Wire
	Textbox txtEmail;
	@Wire
	Textbox txtPassword;
	@Wire
	Textbox txtRePassword;
	@Wire
	Textbox txtFacebook;
	@Wire
	Textbox txtWebsite;
	@Wire
	Radiogroup rdGender;

	@Listen("onClick=#btnSave")
	public void btnSave() {
		user.setSlogan(txtSlogan.getValue());
		user.setName(txtName.getValue());
		user.setBirthday(txtBirthday.getValue());
		user.setLanguage(txtLanguage.getValue());
		user.setWorkplace(txtWorkplace.getValue());
		user.setInterest(txtInterest.getValue());
		user.setFacebook(txtFacebook.getValue());
		user.setWebsite(txtWebsite.getValue());
		if(rdGender.getSelectedItem() == null)
			user.setGender(User.GENDER_UNKNOW);
		else if(rdGender.getSelectedItem().getValue().equals("1"))
			user.setGender(User.GENDER_MALE);
		else if(rdGender.getSelectedItem().getValue().equals("2"))
			user.setGender(User.GENDER_FEMALE);
		
		if(txtPassword.getValue().length() > 0)
			user.setPassword(AAService.hashPassword(txtPassword.getValue()));
		
		UserService usrv = Repository.getInstance().getUserService();
		usrv.save(user);
		
		Utility.redirect("", true);
	}
	
	/**
	 * Check privacy to access profile
	 * @return
	 */
	public boolean checkPrivacy() {
		AAService asrv = Repository.getInstance().getAAService();
		return asrv.checkProfilePrivacy(asrv.getCurrentUser(), getUser(), User.PRIVACYGROUP_PROFILE);
	}
}